#pragma once

#include "../Main/Standard.h"
#include "Utility.h"

////////////////////////////////////////////////////////////////////////////////////////////////////
/// <Summary>	HashString  </Summary>
/// 
/// <purpose>	To Allow easy and fast comparisons between two strings with hash codes	</purpose>
////////////////////////////////////////////////////////////////////////////////////////////////////

class HashString
{
	/// <Summary> The string this hash was made from </Summary>
	const char* strIdentity;

	/// <Summary> The hash code for this instance </Summary>
	unsigned long identity;

public:

	////////////////////////////////////////////////////////////////////////////////////////////////////
	/// <Summary>	Default Constructor </Summary>
	////////////////////////////////////////////////////////////////////////////////////////////////////
	HashString() : strIdentity(NULL), identity(0) { }

	////////////////////////////////////////////////////////////////////////////////////////////////////
	/// <Summary>	Constructor </Summary>
	///
	/// <Param name="str">	The string </Param>
	////////////////////////////////////////////////////////////////////////////////////////////////////
	HashString(const char* const str)
		: strIdentity(Utility::StrCpy(str)), identity(Utility::CreateHash(strIdentity)) 
	{ }

	////////////////////////////////////////////////////////////////////////////////////////////////////
	/// <Summary>	Copy Constructor </Summary>
	///
	/// <Param name="ref">	The other HashString </Param>
	////////////////////////////////////////////////////////////////////////////////////////////////////
	HashString( const HashString& ref )
		: strIdentity(Utility::StrCpy(ref.strIdentity)), identity(ref.identity) 
	{ }

	////////////////////////////////////////////////////////////////////////////////////////////////////
	/// <Summary>	Assignment Operator </Summary>
	///
	/// <Param name="ref">	The other HashString </Param>
	////////////////////////////////////////////////////////////////////////////////////////////////////
	HashString& operator=( const HashString& ref )
	{
		if(this != &ref)
		{
			strIdentity = Utility::StrCpy(ref.strIdentity);
			identity = ref.identity;
		}

		return *this;
	}

	////////////////////////////////////////////////////////////////////////////////////////////////////
	/// <Summary>	Destructor </Summary>
	////////////////////////////////////////////////////////////////////////////////////////////////////
	~HashString()
	{
		if(strIdentity)
			delete[] strIdentity;
	}

	////////////////////////////////////////////////////////////////////////////////////////////////////
	/// <Summary>	Sets this hashstring to a new string </Summary>
	///
	/// <Return>	The string </Return>
	////////////////////////////////////////////////////////////////////////////////////////////////////
	void SetString(const char* string)
	{
		if(strIdentity)
			delete[] strIdentity;

		strIdentity = Utility::StrCpy(string);
		identity = Utility::CreateHash(strIdentity);
	}

	////////////////////////////////////////////////////////////////////////////////////////////////////
	/// <Summary>	Gets the identity </Summary>
	///
	/// <Return>	The identity </Return>
	////////////////////////////////////////////////////////////////////////////////////////////////////

	unsigned long GetIdentity() const
	{
		return identity;
	}

	////////////////////////////////////////////////////////////////////////////////////////////////////
	/// <Summary>	Gets the string </Summary>
	///
	/// <Return>	The string </Return>
	////////////////////////////////////////////////////////////////////////////////////////////////////

	const char* const GetStr() const
	{
		return strIdentity;
	}

	////////////////////////////////////////////////////////////////////////////////////////////////////
	/// <Summary>	Less-than comparison operator </Summary>
	///
	/// <Param name="ref">	The reference </Param>
	///
	/// <Return>	true if the first parameter is less than the second </Return>
	////////////////////////////////////////////////////////////////////////////////////////////////////

	bool operator< ( const HashString& ref ) const
	{
		return GetIdentity() < ref.GetIdentity();
	}

	////////////////////////////////////////////////////////////////////////////////////////////////////
	/// <Summary>	Greater-than comparison operator </Summary>
	///
	/// <Param name="ref">	The reference </Param>
	///
	/// <Return>	true if the first parameter is greater than to the second </Return>
	////////////////////////////////////////////////////////////////////////////////////////////////////

	bool operator> ( const HashString& ref ) const
	{
		return GetIdentity() > ref.GetIdentity();
	}

	////////////////////////////////////////////////////////////////////////////////////////////////////
	/// <Summary>	Less-than-or-equal comparison operator </Summary>
	///
	/// <Param name="ref">	The reference </Param>
	///
	/// <Return>	true if the first parameter is less than or equal to the second </Return>
	////////////////////////////////////////////////////////////////////////////////////////////////////

	bool operator<= ( const HashString& ref ) const
	{
		return GetIdentity() <= ref.GetIdentity();
	}

	////////////////////////////////////////////////////////////////////////////////////////////////////
	/// <Summary>	Greater-than-or-equal comparison operator </Summary>
	///
	/// <Param name="ref">	The reference </Param>
	///
	/// <Return>	true if the first parameter is greater than or equal to the second </Return>
	////////////////////////////////////////////////////////////////////////////////////////////////////

	bool operator>= ( const HashString& ref ) const
	{
		return GetIdentity() >= ref.GetIdentity();
	}

	////////////////////////////////////////////////////////////////////////////////////////////////////
	/// <Summary>	Equality operator </Summary>
	///
	/// <Param name="ref">	The reference </Param>
	///
	/// <Return>	true if the parameters are considered equivalent </Return>
	////////////////////////////////////////////////////////////////////////////////////////////////////

	bool operator== ( const HashString& ref ) const
	{
		return GetIdentity() == ref.GetIdentity();
	}

	////////////////////////////////////////////////////////////////////////////////////////////////////
	/// <Summary>	Non-Equality operator </Summary>
	///
	/// <Param name="ref">	The reference </Param>
	///
	/// <Return>	true if the parameters are considered not equivalent </Return>
	////////////////////////////////////////////////////////////////////////////////////////////////////

	bool operator!= ( const HashString& ref ) const
	{
		return GetIdentity() != ref.GetIdentity();
	}
};